﻿using System;
using System.Collections.Generic;
using System.Text;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.Validation.Interfaces;

using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint;

namespace Kiiro.Validation.Validators.Entities
{
    public class DocumentValidator : BaseEntityValidator, IValidator<Document>
    {
        private readonly List<ValidationMessage> validationErrors = new List<ValidationMessage> ( );

        #region  IValidator<Document> Members
        public List<ValidationMessage> Validate ( Document entityToValidate )
        {
            // If the entity is marked as deleted, don't do any validation, just return.
            if ( entityToValidate.EditType != EditType.Deleted )
            {
                ValidationMessage message = null;
                string propertyName = entityToValidate.IsFolder ? "Folder Name" : "Document";

                #region Required Fields Checks

                message = IsRequired ( entityToValidate.Title, propertyName );

                if ( message != null )
                {
                    entityToValidate.TitleMessage.Add ( message );
                    validationErrors.Add ( message );
                }

                #endregion

                # region Comparison Checks

                if ( !string.IsNullOrEmpty ( entityToValidate.Title ) )
                {
                    if ( entityToValidate.IsFolder )
                        message = HasSpecialCharactersForSiteUrlInText ( entityToValidate, propertyName.ToLower ( ) );
                    else
                        message = HasSpecialCharactersForFileNameOrPathInText ( entityToValidate, "title" );

                    if ( message != null )
                    {
                        entityToValidate.TitleMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.Title ) )
                {
                    if ( entityToValidate.IsFolder )
                    {
                        message = CheckMaximumLength ( 30, entityToValidate.Title, propertyName );

                        if ( message != null )
                        {
                            entityToValidate.TitleMessage.Add ( message );
                            validationErrors.Add ( message );
                        }

                        if ( entityToValidate.TitleMessage.Count == 0 )
                        {
                            message = DoesFolderNameExist ( entityToValidate );

                            if ( message != null )
                            {
                                entityToValidate.TitleMessage.Add ( message );
                                validationErrors.Add ( message );
                            }
                        }
                    }
                    else
                    {
                        message = CheckMaximumLength ( 50, entityToValidate.Title, "Document Title" );

                        if ( message != null )
                        {
                            entityToValidate.TitleMessage.Add ( message );
                            validationErrors.Add ( message );
                        }

                        if ( entityToValidate.TitleMessage.Count == 0 )
                        {
                            message = IsProjectPlanOverwrite ( entityToValidate );

                            if ( message != null )
                            {
                                entityToValidate.TitleMessage.Add ( message );
                                validationErrors.Add ( message );
                            }
                        }

                        if ( entityToValidate.TitleMessage.Count == 0 )
                        {
                            message = DoesFileNameExist ( entityToValidate );

                            if ( message != null )
                            {
                                entityToValidate.TitleMessage.Add ( message );
                                validationErrors.Add ( message );
                            }
                        }
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.Description ) )
                {
                    message = CheckMaximumLength ( 1000, entityToValidate.Description, "Description" );

                    if ( message != null )
                    {
                        entityToValidate.DescriptionMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                #endregion
            }

            return validationErrors;
        }

        #endregion

        private ValidationMessage IsProjectPlanOverwrite ( Document document )
        {
            if ( document.EditType == EditType.Created )
            {
                using ( SPWeb web = SPHelpers.GetWeb ( document.SiteCollectionId, document.ServerRelativeUrl ) )
                {
                    string url = string.IsNullOrEmpty ( document.FolderUrl ) ? "Documents/" + document.Title : document.FolderUrl + "/" + document.Title;
                    SPFile file = web.GetFile ( url );
                    if ( file.Exists && SPDataHelpers.GetBooleanValue ( file.Item, Constants.DocumentFieldNames.IsProjectPlan ) )
                    {
                        return new ValidationMessage ( ValidationSeverity.Validation,
                            "You cannot upload a document to the library that has the same name as this project's plan file. You must use the project settings page to delete or overwrite the plan file." );
                    }
                }
            }

            return null;
        }

        private ValidationMessage DoesFolderNameExist ( Document document )
        {
            ValidationMessage message = null;

            string url = string.IsNullOrEmpty ( document.FolderUrl ) ? "Documents/" + document.Title : document.FolderUrl + "/" + document.Title;

            using ( SPWeb web = SPHelpers.GetWeb ( document.SiteCollectionId, document.ServerRelativeUrl ) )
            {
                if ( web.GetFolder ( url ).Exists )
                {
                    if ( document.EditType == EditType.Created )
                        message = new ValidationMessage ( ValidationSeverity.Validation, "Cannot create folder. A folder with that name already exists." );
                    else if ( document.EditType == EditType.Updated )
                        message = new ValidationMessage ( ValidationSeverity.Validation, "Cannot rename folder. A folder with that name already exists." );
                }
                else if ( web.GetFile ( url ).Exists )
                    message = new ValidationMessage ( ValidationSeverity.Validation, "Cannot create folder. A file with that name already exists." );
            }

            return message;
        }

        private ValidationMessage DoesFileNameExist ( Document document )
        {
            ValidationMessage message = null;

            string url = string.IsNullOrEmpty ( document.FolderUrl ) ? "Documents/" + document.Title : document.FolderUrl + "/" + document.Title;

            using ( SPWeb web = SPHelpers.GetWeb ( document.SiteCollectionId, document.ServerRelativeUrl ) )
            {
                if ( web.GetFolder ( url ).Exists )
                {
                    if ( document.EditType == EditType.Created )
                        message = new ValidationMessage ( ValidationSeverity.Validation, "Cannot create file. A folder with that name already exists." );
                    else if ( document.EditType == EditType.Updated )
                        message = new ValidationMessage ( ValidationSeverity.Validation, "Cannot rename file. A folder with that name already exists." );
                }
                else if ( web.GetFile ( url ).Exists )
                {
                    if ( document.EditType == EditType.Updated )
                        message = new ValidationMessage ( ValidationSeverity.Validation, "Cannot rename file. A file with that name already exists." );
                }
            }

            return message;
        }
    }
}
/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Validation/Validators/Entities/DocumentValidator.cs $
 * 
 * 10    2/08/10 12:00p Camerons
 * 
 * 9     10/11/09 11:40a Camerons
 * 
 * 8     10/23/09 1:40p Adamw
 * moved folder and file path validation to BaseEntityValidator
 * 
 * 7     10/21/09 11:44a Adamw
 * Case 350, added a trim to the input text fields, added some clearer
 * error messages to document and folder name validation, removed isFolder
 * check from IsFolderNameValid as special chars are invlid for full url
 * 
 * 6     17/08/09 10:45a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/